<template>
	<view class="chart-container">
		<view class="chart-header" v-if="title">
			<text class="chart-title">{{ title }}</text>
			<view class="chart-legend" v-if="showLegend">
				<view class="legend-item" v-for="(item, index) in legendData" :key="index">
					<view class="legend-color" :style="{ backgroundColor: item.color }"></view>
					<text class="legend-text">{{ item.name }}</text>
				</view>
			</view>
		</view>
		
		<view class="chart-content">
			<canvas 
				:canvas-id="canvasId" 
				class="chart-canvas"
				:style="{ width: width + 'px', height: height + 'px' }"
				@touchstart="handleTouchStart"
				@touchmove="handleTouchMove"
				@touchend="handleTouchEnd"
			></canvas>
			
			<!-- 数据点提示 -->
			<view 
				class="tooltip" 
				v-if="showTooltip"
				:style="{ 
					left: tooltipX + 'px', 
					top: tooltipY + 'px' 
				}"
			>
				<text class="tooltip-text">{{ tooltipText }}</text>
			</view>
		</view>
		
		<!-- X轴标签 -->
		<view class="x-axis-labels" v-if="xAxisLabels.length">
			<text 
				v-for="(label, index) in xAxisLabels" 
				:key="index"
				class="x-label"
				:style="{ width: (100 / xAxisLabels.length) + '%' }"
			>
				{{ label }}
			</text>
		</view>
	</view>
</template>

<script>
export default {
	name: 'LineChart',
	props: {
		title: {
			type: String,
			default: ''
		},
		data: {
			type: Array,
			required: true
		},
		width: {
			type: Number,
			default: 350
		},
		height: {
			type: Number,
			default: 200
		},
		lineColor: {
			type: String,
			default: '#2196F3'
		},
		fillColor: {
			type: String,
			default: 'rgba(33, 150, 243, 0.1)'
		},
		showPoints: {
			type: Boolean,
			default: true
		},
		showGrid: {
			type: Boolean,
			default: true
		},
		showLegend: {
			type: Boolean,
			default: false
		},
		legendData: {
			type: Array,
			default: () => []
		},
		xAxisLabels: {
			type: Array,
			default: () => []
		},
		canvasId: {
			type: String,
			default: 'lineChart'
		}
	},
	data() {
		return {
			showTooltip: false,
			tooltipX: 0,
			tooltipY: 0,
			tooltipText: '',
			ctx: null,
			padding: 40
		}
	},
	mounted() {
		this.$nextTick(() => {
			this.initChart();
		});
	},
	watch: {
		data: {
			handler() {
				this.$nextTick(() => {
					this.drawChart();
				});
			},
			deep: true
		}
	},
	methods: {
		initChart() {
			this.ctx = uni.createCanvasContext(this.canvasId, this);
			this.drawChart();
		},
		
		drawChart() {
			if (!this.ctx || !this.data.length) return;
			
			const { ctx, width, height, padding, data } = this;
			
			// 清空画布
			ctx.clearRect(0, 0, width, height);
			
			// 绘制背景
			ctx.setFillStyle('#ffffff');
			ctx.fillRect(0, 0, width, height);
			
			// 计算数据范围
			const maxValue = Math.max(...data);
			const minValue = Math.min(...data);
			const range = maxValue - minValue || 1;
			
			// 计算坐标系
			const chartWidth = width - padding * 2;
			const chartHeight = height - padding * 2;
			const stepX = chartWidth / (data.length - 1);
			
			// 绘制网格线
			if (this.showGrid) {
				this.drawGrid(chartWidth, chartHeight);
			}
			
			// 绘制填充区域
			this.drawFillArea(data, stepX, chartHeight, range, minValue);
			
			// 绘制折线
			this.drawLine(data, stepX, chartHeight, range, minValue);
			
			// 绘制数据点
			if (this.showPoints) {
				this.drawPoints(data, stepX, chartHeight, range, minValue);
			}
			
			ctx.draw();
		},
		
		drawGrid(chartWidth, chartHeight) {
			const { ctx, padding } = this;
			
			ctx.setStrokeStyle('#f0f0f0');
			ctx.setLineWidth(1);
			
			// 水平网格线
			for (let i = 0; i <= 5; i++) {
				const y = padding + chartHeight * i / 5;
				ctx.beginPath();
				ctx.moveTo(padding, y);
				ctx.lineTo(padding + chartWidth, y);
				ctx.stroke();
			}
			
			// 垂直网格线
			for (let i = 0; i < this.data.length; i++) {
				const x = padding + i * (chartWidth / (this.data.length - 1));
				ctx.beginPath();
				ctx.moveTo(x, padding);
				ctx.lineTo(x, padding + chartHeight);
				ctx.stroke();
			}
		},
		
		drawFillArea(data, stepX, chartHeight, range, minValue) {
			const { ctx, padding, fillColor } = this;
			
			ctx.setFillStyle(fillColor);
			ctx.beginPath();
			
			// 起始点
			ctx.moveTo(padding, padding + chartHeight);
			
			// 绘制数据点
			data.forEach((value, index) => {
				const x = padding + index * stepX;
				const y = padding + chartHeight - ((value - minValue) / range) * chartHeight;
				ctx.lineTo(x, y);
			});
			
			// 结束点
			ctx.lineTo(padding + (data.length - 1) * stepX, padding + chartHeight);
			ctx.closePath();
			ctx.fill();
		},
		
		drawLine(data, stepX, chartHeight, range, minValue) {
			const { ctx, padding, lineColor } = this;
			
			ctx.setStrokeStyle(lineColor);
			ctx.setLineWidth(3);
			ctx.beginPath();
			
			data.forEach((value, index) => {
				const x = padding + index * stepX;
				const y = padding + chartHeight - ((value - minValue) / range) * chartHeight;
				
				if (index === 0) {
					ctx.moveTo(x, y);
				} else {
					ctx.lineTo(x, y);
				}
			});
			
			ctx.stroke();
		},
		
		drawPoints(data, stepX, chartHeight, range, minValue) {
			const { ctx, padding, lineColor } = this;
			
			ctx.setFillStyle(lineColor);
			
			data.forEach((value, index) => {
				const x = padding + index * stepX;
				const y = padding + chartHeight - ((value - minValue) / range) * chartHeight;
				
				// 绘制外圈
				ctx.beginPath();
				ctx.arc(x, y, 6, 0, 2 * Math.PI);
				ctx.setFillStyle('#ffffff');
				ctx.fill();
				
				// 绘制内圈
				ctx.beginPath();
				ctx.arc(x, y, 4, 0, 2 * Math.PI);
				ctx.setFillStyle(lineColor);
				ctx.fill();
			});
		},
		
		handleTouchStart(e) {
			const touch = e.touches[0];
			this.showTooltipAtPosition(touch.x, touch.y);
		},
		
		handleTouchMove(e) {
			const touch = e.touches[0];
			this.showTooltipAtPosition(touch.x, touch.y);
		},
		
		handleTouchEnd() {
			this.hideTooltip();
		},
		
		showTooltipAtPosition(x, y) {
			const { data, padding, width } = this;
			const chartWidth = width - padding * 2;
			const stepX = chartWidth / (data.length - 1);
			
			// 计算最近的数据点
			const relativeX = x - padding;
			const index = Math.round(relativeX / stepX);
			
			if (index >= 0 && index < data.length) {
				this.showTooltip = true;
				this.tooltipX = x;
				this.tooltipY = y - 40;
				this.tooltipText = `${data[index]}`;
			}
		},
		
		hideTooltip() {
			setTimeout(() => {
				this.showTooltip = false;
			}, 1000);
		}
	}
}
</script>

<style lang="scss" scoped>
.chart-container {
	background-color: #fff;
	border-radius: 12px;
	padding: 20px;
	position: relative;
	
	.chart-header {
		margin-bottom: 20px;
		
		.chart-title {
			font-size: 16px;
			font-weight: bold;
			color: #333;
			display: block;
			margin-bottom: 10px;
		}
		
		.chart-legend {
			display: flex;
			flex-wrap: wrap;
			
			.legend-item {
				display: flex;
				align-items: center;
				margin-right: 20px;
				margin-bottom: 5px;
				
				.legend-color {
					width: 12px;
					height: 12px;
					border-radius: 6px;
					margin-right: 6px;
				}
				
				.legend-text {
					font-size: 12px;
					color: #666;
				}
			}
		}
	}
	
	.chart-content {
		position: relative;
		
		.chart-canvas {
			width: 100%;
		}
		
		.tooltip {
			position: absolute;
			background-color: rgba(0, 0, 0, 0.8);
			color: #fff;
			padding: 6px 10px;
			border-radius: 4px;
			font-size: 12px;
			pointer-events: none;
			z-index: 10;
			
			.tooltip-text {
				color: #fff;
			}
		}
	}
	
	.x-axis-labels {
		display: flex;
		margin-top: 10px;
		padding: 0 40px;
		
		.x-label {
			text-align: center;
			font-size: 12px;
			color: #666;
		}
	}
}
</style>
